home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / octa209s.zip / octave-2.09 / src / unwind-prot.cc < prev    next >
C/C++ Source or Header  |  1997-01-29  |  5KB  |  269 lines

  1. /*
  2.  
  3. Copyright (C) 1996 John W. Eaton
  4.  
  5. This file is part of Octave.
  6.  
  7. Octave is free software; you can redistribute it and/or modify it
  8. under the terms of the GNU General Public License as published by the
  9. Free Software Foundation; either version 2, or (at your option) any
  10. later version.
  11.  
  12. Octave is distributed in the hope that it will be useful, but WITHOUT
  13. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15. for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with Octave; see the file COPYING.  If not, write to the Free
  19. Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. */
  22.  
  23. #if defined (__GNUG__)
  24. #pragma implementation
  25. #endif
  26.  
  27. #ifdef HAVE_CONFIG_H
  28. #include <config.h>
  29. #endif
  30.  
  31. #include <cstddef>
  32.  
  33. #include <string>
  34.  
  35. #include "SLStack.h"
  36.  
  37. #include "CMatrix.h"
  38.  
  39. #include "error.h"
  40. #include "unwind-prot.h"
  41. #include "utils.h"
  42.  
  43. // XXX FIXME XXX -- this should really be static, but that causes
  44. // problems on some systems.
  45. SLStack <unwind_elem> unwind_protect_list;
  46.  
  47. void
  48. add_unwind_protect (cleanup_func fptr, void *ptr)
  49. {
  50.   unwind_elem el (fptr, ptr);
  51.   unwind_protect_list.push (el);
  52. }
  53.  
  54. void
  55. run_unwind_protect (void)
  56. {
  57.   unwind_elem el = unwind_protect_list.pop ();
  58.  
  59.   cleanup_func f = el.fptr ();
  60.  
  61.   if (f)
  62.     f (el.ptr ());
  63. }
  64.  
  65. void
  66. discard_unwind_protect (void)
  67. {
  68.   unwind_protect_list.pop ();
  69. }
  70.  
  71. void
  72. begin_unwind_frame (const string& tag)
  73. {
  74.   unwind_elem elem (tag);
  75.   unwind_protect_list.push (elem);
  76. }
  77.  
  78. void
  79. run_unwind_frame (const string& tag)
  80. {
  81.   while (! unwind_protect_list.empty ())
  82.     {
  83.       unwind_elem el = unwind_protect_list.pop ();
  84.  
  85.       cleanup_func f = el.fptr ();
  86.  
  87.       if (f)
  88.     f (el.ptr ());
  89.  
  90.       if (tag == el.tag ())
  91.     break;
  92.     }
  93. }
  94.  
  95. void
  96. discard_unwind_frame (const string& tag)
  97. {
  98.   while (! unwind_protect_list.empty ())
  99.     {
  100.       unwind_elem el = unwind_protect_list.pop ();
  101.  
  102.       if (tag == el.tag ())
  103.     break;
  104.     }
  105. }
  106.  
  107. void
  108. run_all_unwind_protects (void)
  109. {
  110.   while (! unwind_protect_list.empty ())
  111.     {
  112.       unwind_elem el = unwind_protect_list.pop ();
  113.  
  114.       cleanup_func f = el.fptr ();
  115.  
  116.       if (f)
  117.     f (el.ptr ());
  118.     }
  119. }
  120.  
  121. void
  122. discard_all_unwind_protects (void)
  123. {
  124.   unwind_protect_list.clear ();
  125. }
  126.  
  127. class saved_variable
  128. {
  129.  public:
  130.   enum var_type { integer, string_type, generic_ptr, generic };
  131.  
  132.   saved_variable (void);
  133.   saved_variable (int *p, int v);
  134.   saved_variable (string *p, const string& v);
  135.   saved_variable (void **p, void *v);
  136.   ~saved_variable (void);
  137.  
  138.   void restore_value (void);
  139.  
  140.  private:
  141.   union
  142.     {
  143.       int *ptr_to_int;
  144.       void *gen_ptr;
  145.       void **ptr_to_gen_ptr;
  146.     };
  147.  
  148.   union
  149.     {
  150.       int int_value;
  151.       const string *str_value;
  152.       void *gen_ptr_value;
  153.     };
  154.  
  155.   var_type type_tag;
  156.   size_t size;
  157. };
  158.  
  159. saved_variable::saved_variable (void)
  160. {
  161.   gen_ptr = 0;
  162.   gen_ptr_value = 0;
  163.   type_tag = generic;
  164.   size = 0;
  165. }
  166.  
  167. saved_variable::saved_variable (int *p, int v)
  168. {
  169.   type_tag = integer;
  170.   ptr_to_int = p;
  171.   int_value = v;
  172.   size = sizeof (int);  // Is this necessary?
  173. }
  174.  
  175. saved_variable::saved_variable (string *p, const string& v)
  176. {
  177.   type_tag = string_type;
  178.   gen_ptr = p;
  179.   str_value = new string (v);
  180.   size = sizeof (string);  // Is this necessary?
  181. }
  182.  
  183. saved_variable::saved_variable (void **p, void *v)
  184. {
  185.   type_tag = generic_ptr;
  186.   ptr_to_gen_ptr = p;
  187.   gen_ptr_value = v;
  188.   size = sizeof (void *);
  189. }
  190.  
  191. saved_variable::~saved_variable (void)
  192. {
  193.   switch (type_tag)
  194.     {
  195.     case string_type:
  196.       delete str_value;
  197.       break;
  198.  
  199.     case generic:
  200.       delete [] gen_ptr_value;  // Can this be right?
  201.       break;
  202.  
  203.     default:
  204.       break;
  205.     }
  206. }
  207.  
  208. void
  209. saved_variable::restore_value (void)
  210. {
  211.   switch (type_tag)
  212.     {
  213.     case integer:
  214.       *ptr_to_int = int_value;
  215.       break;
  216.  
  217.     case string_type:
  218.       ((string *) gen_ptr) -> assign (*str_value);
  219.       break;
  220.  
  221.     case generic_ptr:
  222.       *ptr_to_gen_ptr = gen_ptr_value;
  223.       break;
  224.  
  225.     case generic:
  226.       memcpy (gen_ptr, gen_ptr_value, size);
  227.       break;
  228.  
  229.     default:
  230.       panic_impossible ();
  231.       break;
  232.     }
  233. }
  234.  
  235. static void
  236. restore_saved_variable (void *s)
  237. {
  238.   saved_variable *sv = (saved_variable *) s;
  239.   sv->restore_value ();
  240.   delete sv;
  241. }
  242.  
  243. void
  244. unwind_protect_int_internal (int *ptr, int value)
  245. {
  246.   saved_variable *s = new saved_variable (ptr, value);
  247.   add_unwind_protect (restore_saved_variable, (void *) s);
  248. }
  249.  
  250. void
  251. unwind_protect_str_internal (string *ptr, const string& value)
  252. {
  253.   saved_variable *s = new saved_variable (ptr, value);
  254.   add_unwind_protect (restore_saved_variable, (void *) s);
  255. }
  256.  
  257. void
  258. unwind_protect_ptr_internal (void **ptr, void *value)
  259. {
  260.   saved_variable *s = new saved_variable (ptr, value);
  261.   add_unwind_protect (restore_saved_variable, (void *) s);
  262. }
  263.  
  264. /*
  265. ;;; Local Variables: ***
  266. ;;; mode: C++ ***
  267. ;;; End: ***
  268. */
  269.